<template>
  <div class="data-table-container">
    <el-card class="table-card">
      <template #header>
        <div class="card-header">
          <span>数据表格</span>
          <el-button type="primary" @click="refreshData">
            <el-icon><Refresh /></el-icon>
            刷新数据
          </el-button>
        </div>
      </template>
      
      <el-table
        :data="tableData"
        style="width: 100%"
        v-loading="loading"
        stripe
        border
        height="500"
      >
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="name" label="姓名" width="120" />
        <el-table-column prop="email" label="邮箱" width="200" />
        <el-table-column prop="department" label="部门" width="120" />
        <el-table-column prop="position" label="职位" width="120" />
        <el-table-column prop="salary" label="薪资" width="100">
          <template #default="scope">
            <span class="salary-text">¥{{ scope.row.salary.toLocaleString() }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <el-tag :type="getStatusType(scope.row.status)">
              {{ scope.row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="160" />
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="scope">
            <el-button
              type="primary"
              size="small"
              @click="toggleDownloadOptions(scope.row, $event)"
              :loading="scope.row.downloading?.pdf || scope.row.downloading?.odf || scope.row.downloading?.xml"
            >
              <el-icon><Download /></el-icon>
              下载
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <!-- 自定义弹窗 -->
      <div 
        v-if="showCustomPopover" 
        class="custom-download-popover"
        :style="popoverStyle"
        @click.stop
      >
        <div class="download-options">
          <div 
            class="download-option" 
            @click="currentRow && downloadFile(currentRow, 'pdf')"
            :class="{ loading: currentRow?.downloading?.pdf }"
          >
            <el-icon><component :is="Document" /></el-icon>
            <span>下载PDF</span>
          </div>
          <div 
            class="download-option" 
            @click="currentRow && downloadFile(currentRow, 'odf')"
            :class="{ loading: currentRow?.downloading?.odf }"
          >
            <el-icon><component :is="Document" /></el-icon>
            <span>下载ODF</span>
          </div>
          <div 
            class="download-option" 
            @click="currentRow && downloadFile(currentRow, 'xml')"
            :class="{ loading: currentRow?.downloading?.xml }"
          >
            <el-icon><component :is="Document" /></el-icon>
            <span>下载XML</span>
          </div>
        </div>
      </div>
      
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
// @ts-ignore
import { Download, Document } from '@element-plus/icons-vue'

// 定义数据类型
interface TableDataItem {
  id: number
  name: string
  email: string
  department: string
  position: string
  salary: number
  status: string
  createTime: string
  downloading?: {
    pdf?: boolean
    odf?: boolean
    xml?: boolean
  }
}

// 响应式数据
const loading = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)

// 自定义弹窗相关数据
const showCustomPopover = ref(false)
const currentRow = ref<TableDataItem | null>(null)
const currentButton = ref<HTMLElement | null>(null)
const popoverStyle = ref<{
  position: 'absolute' | 'fixed'
  left: string
  top: string
  zIndex: number
}>({
  position: 'absolute',
  left: '0px',
  top: '0px',
  zIndex: 2000
})

// 模拟数据
const allData = ref<TableDataItem[]>([])

// 计算属性 - 当前页数据
const tableData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return allData.value.slice(start, end)
})

// 生成模拟数据
const generateMockData = () => {
  const departments = ['技术部', '市场部', '人事部', '财务部', '运营部']
  const positions = ['经理', '主管', '专员', '助理', '总监']
  const statuses = ['在职', '离职', '试用期']
  const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十', '郑十一', '王十二']
  
  const data: TableDataItem[] = []
  
  for (let i = 1; i <= 100; i++) {
    const randomDept = departments[Math.floor(Math.random() * departments.length)]
    const randomPos = positions[Math.floor(Math.random() * positions.length)]
    const randomStatus = statuses[Math.floor(Math.random() * statuses.length)]
    const randomName = names[Math.floor(Math.random() * names.length)]
    
    data.push({
      id: i,
      name: `${randomName}${i}`,
      email: `user${i}@company.com`,
      department: randomDept,
      position: randomPos,
      salary: Math.floor(Math.random() * 50000) + 5000,
      status: randomStatus,
      createTime: new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000).toLocaleDateString(),
      downloading: {
        pdf: false,
        odf: false,
        xml: false
      }
    })
  }
  
  return data
}

// 获取状态标签类型
const getStatusType = (status: string) => {
  switch (status) {
    case '在职':
      return 'success'
    case '离职':
      return 'danger'
    case '试用期':
      return 'warning'
    default:
      return 'info'
  }
}

// 切换下载选项弹窗显示状态
const toggleDownloadOptions = (row: TableDataItem, event: MouseEvent) => {
  if (showCustomPopover.value && currentRow.value?.id === row.id) {
    // 如果当前弹窗就是这一行的，则关闭
    showCustomPopover.value = false
    currentRow.value = null
    currentButton.value = null
  } else {
    // 显示弹窗并定位
    currentRow.value = row
    currentButton.value = event.target as HTMLElement
    showCustomPopover.value = true
    
    // 计算按钮位置
    const buttonElement = event.target as HTMLElement
    const buttonRect = buttonElement.getBoundingClientRect()
    
    // 计算弹窗位置（在按钮下方居中）
    const popoverWidth = 160
    const popoverHeight = 120 // 估算高度
    const offset = 8
    
    const left = buttonRect.left + (buttonRect.width - popoverWidth) / 2
    const top = buttonRect.bottom + offset
    
    // 边界检测
    const viewportWidth = window.innerWidth
    const viewportHeight = window.innerHeight
    
    let finalLeft = left
    let finalTop = top
    
    // 右边界检测
    if (left + popoverWidth > viewportWidth) {
      finalLeft = viewportWidth - popoverWidth - 10
    }
    
    // 左边界检测
    if (left < 10) {
      finalLeft = 10
    }
    
    // 下边界检测
    if (top + popoverHeight > viewportHeight) {
      finalTop = buttonRect.top - popoverHeight - offset
    }
    
    // 应用位置
    popoverStyle.value = {
      position: 'fixed' as const,
      left: finalLeft + 'px',
      top: finalTop + 'px',
      zIndex: 2000
    }
  }
}

// 下载文件
const downloadFile = async (row: TableDataItem, type: 'pdf' | 'odf' | 'xml') => {
  try {
    // 设置下载状态
    if (!row.downloading) {
      row.downloading = {}
    }
    row.downloading[type] = true
    
    // 模拟下载延迟
    await new Promise(resolve => setTimeout(resolve, 1500))
    
    // 根据类型生成不同的内容
    let content = ''
    let filename = ''
    let mimeType = ''
    
    const baseInfo = `员工信息详情
==================
姓名: ${row.name}
邮箱: ${row.email}
部门: ${row.department}
职位: ${row.position}
薪资: ¥${row.salary.toLocaleString()}
状态: ${row.status}
创建时间: ${row.createTime}
==================
下载时间: ${new Date().toLocaleString()}`
    
    if (type === 'pdf') {
      content = baseInfo
      filename = `员工信息_${row.name}_${Date.now()}.txt`
      mimeType = 'text/plain;charset=utf-8'
    } else if (type === 'odf') {
      content = `<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0">
  <office:body>
    <office:text>
      <text:p>${baseInfo.replace(/\n/g, '</text:p><text:p>')}</text:p>
    </office:text>
  </office:body>
</office:document>`
      filename = `员工信息_${row.name}_${Date.now()}.odt`
      mimeType = 'application/vnd.oasis.opendocument.text'
    } else if (type === 'xml') {
      content = `<?xml version="1.0" encoding="UTF-8"?>
<employee>
  <name>${row.name}</name>
  <email>${row.email}</email>
  <department>${row.department}</department>
  <position>${row.position}</position>
  <salary>${row.salary}</salary>
  <status>${row.status}</status>
  <createTime>${row.createTime}</createTime>
  <downloadTime>${new Date().toLocaleString()}</downloadTime>
</employee>`
      filename = `员工信息_${row.name}_${Date.now()}.xml`
      mimeType = 'application/xml;charset=utf-8'
    }
    
    // 创建下载链接
    const blob = new Blob([content], { type: mimeType })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = filename
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success(`${type.toUpperCase()}文件下载成功！`)
    
    // 不自动隐藏弹窗，让用户可以选择其他格式
    
  } catch (error) {
    ElMessage.error('下载失败，请重试')
    console.error('下载错误:', error)
  } finally {
    // 重置下载状态
    if (row.downloading) {
      row.downloading[type] = false
    }
  }
}

// 刷新数据
const refreshData = async () => {
  loading.value = true
  try {
    // 模拟API调用延迟
    await new Promise(resolve => setTimeout(resolve, 1000))
    allData.value = generateMockData()
    total.value = allData.value.length
    currentPage.value = 1
    ElMessage.success('数据刷新成功！')
  } catch (error) {
    ElMessage.error('数据刷新失败')
  } finally {
    loading.value = false
  }
}

// 分页处理
const handleSizeChange = (val: number) => {
  pageSize.value = val
  currentPage.value = 1
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
}

// 全局变量，用于事件监听器
let updateTimer: number | null = null
let rafId: number | null = null
let throttledUpdatePosition: (() => void) | null = null

// 监听窗口大小变化和滚动，重新定位弹窗
const updatePopoverPosition = () => {
  if (showCustomPopover.value && currentButton.value) {
    const buttonRect = currentButton.value.getBoundingClientRect()
    const popoverWidth = 160
    const popoverHeight = 120
    const offset = 8
    
    const left = buttonRect.left + (buttonRect.width - popoverWidth) / 2
    const top = buttonRect.bottom + offset
    
    // 边界检测
    const viewportWidth = window.innerWidth
    const viewportHeight = window.innerHeight
    
    let finalLeft = left
    let finalTop = top
    
    // 右边界检测
    if (left + popoverWidth > viewportWidth) {
      finalLeft = viewportWidth - popoverWidth - 10
    }
    
    // 左边界检测
    if (left < 10) {
      finalLeft = 10
    }
    
    // 下边界检测
    if (top + popoverHeight > viewportHeight) {
      finalTop = buttonRect.top - popoverHeight - offset
    }
    
    // 调试信息
    console.log('更新弹窗位置:', {
      buttonRect,
      finalLeft,
      finalTop,
      scrollY: window.scrollY
    })
    
    popoverStyle.value = {
      position: 'fixed' as const,
      left: finalLeft + 'px',
      top: finalTop + 'px',
      zIndex: 2000
    }
  }
}

// 组件挂载时初始化数据
onMounted(() => {
  allData.value = generateMockData()
  total.value = allData.value.length
  
  // 添加全局点击事件，点击外部时隐藏弹窗
  document.addEventListener('click', (event) => {
    const target = event.target as HTMLElement
    // 检查点击是否在弹窗内容区域或按钮内部
    if (!target.closest('.custom-download-popover') && !target.closest('.el-button')) {
      showCustomPopover.value = false
      currentRow.value = null
      currentButton.value = null
    }
  })
  
  // 节流函数，避免频繁更新位置
  throttledUpdatePosition = () => {
    if (rafId) {
      cancelAnimationFrame(rafId)
    }
    rafId = requestAnimationFrame(() => {
      updatePopoverPosition()
    })
  }
  
  // 监听多种滚动事件
  window.addEventListener('resize', throttledUpdatePosition)
  window.addEventListener('scroll', throttledUpdatePosition, true) // 使用捕获模式
  
  // 监听表格容器的滚动
  const tableContainer = document.querySelector('.data-table-container')
  if (tableContainer) {
    tableContainer.addEventListener('scroll', throttledUpdatePosition)
  }
  
  // 监听表格本身的滚动
  const tableElement = document.querySelector('.el-table')
  if (tableElement) {
    tableElement.addEventListener('scroll', throttledUpdatePosition)
  }
  
  // 监听表格体部的滚动
  const tableBody = document.querySelector('.el-table__body-wrapper')
  if (tableBody) {
    tableBody.addEventListener('scroll', throttledUpdatePosition)
  }
})

// 组件卸载时清理事件监听器
onUnmounted(() => {
  if (throttledUpdatePosition) {
    window.removeEventListener('resize', throttledUpdatePosition)
    window.removeEventListener('scroll', throttledUpdatePosition, true)
    
    const tableContainer = document.querySelector('.data-table-container')
    if (tableContainer) {
      tableContainer.removeEventListener('scroll', throttledUpdatePosition)
    }
    
    const tableElement = document.querySelector('.el-table')
    if (tableElement) {
      tableElement.removeEventListener('scroll', throttledUpdatePosition)
    }
    
    const tableBody = document.querySelector('.el-table__body-wrapper')
    if (tableBody) {
      tableBody.removeEventListener('scroll', throttledUpdatePosition)
    }
  }
  
  // 清理定时器
  if (updateTimer) {
    clearTimeout(updateTimer)
  }
  if (rafId) {
    cancelAnimationFrame(rafId)
  }
})
</script>

<style scoped>
.data-table-container {
  padding: 20px;
}

.table-card {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 18px;
  font-weight: bold;
}

.salary-text {
  color: #67c23a;
  font-weight: bold;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

:deep(.el-table .el-table__row:hover) {
  background-color: #f5f7fa;
}

:deep(.el-button + .el-button) {
  margin-left: 8px;
}

.custom-download-popover {
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  width: 160px;
}

.download-options {
  padding: 8px 0;
  position: relative;
  z-index: 1000;
}

.download-option {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  cursor: pointer;
  transition: background-color 0.2s;
  border-radius: 4px;
  margin: 2px 0;
}

.download-option:hover {
  background-color: #f5f7fa;
}

.download-option.loading {
  opacity: 0.6;
  cursor: not-allowed;
}

.download-option .el-icon {
  margin-right: 8px;
  font-size: 14px;
}

.download-option span {
  font-size: 14px;
  color: #606266;
}
</style>
